# -*- coding:utf-8 -*-
# @FileName : app\api\v1\conversations\routes.py
# @Time     : 2025/11/28
# @Author   : 天空之城
"""
    发送消息给 Agent：
    - 返回 AI 思考步骤（thought）
    - 返回最终回复 + 工具调用日志（tool_execution_logs）
    - 确保所有消息和步骤都保存到数据库
    """
from flask import Blueprint, request
from flask_jwt_extended import jwt_required, get_jwt_identity

from app.api.v1.conversations.services import ConversationService, MessageService
from app.api.v1.conversations.schemas import ConversationSchema, MessageSchema
from app.config import logger
from app.utils.response_factory import ResponseFactory
from app.services.agent_service import AgentService
from app.models.conversation import MessageRole

conversations_bp = Blueprint('conversations', __name__)

conversation_service = ConversationService()
message_service = MessageService()
conversation_schema = ConversationSchema()
message_schema = MessageSchema()
messages_schema = MessageSchema(many=True)


# --------------------------------------------------------
# 获取所有对话
# --------------------------------------------------------
@conversations_bp.route('', methods=['GET'])
@jwt_required()
def get_conversations():
    try:
        user_id = get_jwt_identity()
        logger.info(f"用户 {user_id} 请求获取对话列表")
        
        conversations, _ = conversation_service.get_user_conversations(user_id)
        logger.info(f"用户 {user_id} 成功获取对话列表，共 {len(conversations)} 个对话")

        return ResponseFactory.success(
            data=[conversation_schema.dump(conv) for conv in conversations]
        )
    except Exception as e:
        logger.error(f"用户 {user_id} 获取对话列表失败: {str(e)}", exc_info=True)
        return ResponseFactory.error(
            code="CONVERSATION_FETCH_FAILED",
            message=f"获取对话列表失败: {str(e)}"
        )


# --------------------------------------------------------
# 获取单个对话
# --------------------------------------------------------
@conversations_bp.route('/<int:conversation_id>', methods=['GET'])
@jwt_required()
def get_conversation(conversation_id):
    try:
        user_id = get_jwt_identity()
        logger.info(f"用户 {user_id} 请求获取对话 {conversation_id} 的详情")

        conversation = conversation_service.get_conversation_by_id(conversation_id, user_id)
        if not conversation:
            logger.warning(f"用户 {user_id} 尝试访问不存在或无权限的对话 {conversation_id}")
            return ResponseFactory.error(
                code="CONVERSATION_NOT_FOUND",
                msg="对话不存在或无权限访问",
                errors=None
            )

        logger.info(f"用户 {user_id} 成功获取对话 {conversation_id} 的详情")
        return ResponseFactory.success(
            data=conversation_schema.dump(conversation)
        )
    except Exception as e:
        logger.error(f"用户 {user_id} 获取对话 {conversation_id} 详情失败: {str(e)}", exc_info=True)
        return ResponseFactory.error(
            code="CONVERSATION_FETCH_FAILED",
            msg=f"获取对话详情失败: {str(e)}"
        )


# --------------------------------------------------------
# 创建对话
# --------------------------------------------------------
@conversations_bp.route('', methods=['POST'])
@jwt_required()
def create_conversation():
    try:
        user_id = get_jwt_identity()
        logger.info(f"用户 {user_id} 请求创建对话")

        if not request.is_json:
            logger.warning(f"用户 {user_id} 创建对话请求格式错误，不是 JSON")
            return ResponseFactory.error(
                code="INVALID_CONTENT_TYPE",
                msg="请求内容必须是 JSON"
            )

        data = request.get_json()
        logger.info(f"用户 {user_id} 创建对话请求数据: {data}")
        
        title = data.get('title', '').strip()
        content = data.get('content', '').strip()

        if not title:
            logger.warning(f"用户 {user_id} 创建对话请求标题为空")
            return ResponseFactory.error(
                code="INVALID_TITLE",
                msg="标题不能为空"
            )

        from app.models.conversation import ConversationMode
        mode = data.get("mode", "chat")
        try:
            mode_enum = ConversationMode(mode)
        except Exception as e:
            logger.warning(f"用户 {user_id} 创建对话请求模式 {mode} 无效，使用默认值 chat: {str(e)}")
            mode_enum = ConversationMode.CHAT

        logger.info(f"用户 {user_id} 创建对话，标题: {title}, 模式: {mode_enum}, 内容长度: {len(content)}")
        
        conversation = conversation_service.create_conversation(
            user_id=user_id,
            title=title,
            mode=mode_enum
        )

        logger.info(f"用户 {user_id} 成功创建对话，对话ID: {conversation.id}, 标题: {title}")
        
        return ResponseFactory.success(
            data=conversation_schema.dump(conversation)
        )
    except Exception as e:
        logger.error(f"用户创建对话失败: {str(e)}", exc_info=True)
        return ResponseFactory.error(
            code="CONVERSATION_CREATE_FAILED",
            msg=f"创建对话失败: {str(e)}"
        )


# --------------------------------------------------------
# 更新对话
# --------------------------------------------------------
@conversations_bp.route('/<int:conversation_id>', methods=['PUT'])
@jwt_required()
def update_conversation(conversation_id):
    try:
        user_id = get_jwt_identity()
        conversation = conversation_service.get_conversation_by_id(conversation_id, user_id)

        if not conversation:
            return ResponseFactory.error(
                code="CONVERSATION_NOT_FOUND",
                msg="对话不存在或无权限访问"
            )

        if not request.is_json:
            return ResponseFactory.error(
                code="INVALID_CONTENT_TYPE",
                msg="请求内容必须是 JSON"
            )

        data = request.get_json()
        new_data = {}

        if 'title' in data:
            if not data['title'].strip():
                return ResponseFactory.error(
                    code="INVALID_TITLE",
                    msg="标题不能为空"
                )
            new_data["title"] = data["title"]

        if 'status' in data:
            new_data["status"] = data["status"]

        updated = conversation_service.update_conversation(
            conversation_id, user_id, **new_data
        )

        return ResponseFactory.success(
            data=conversation_schema.dump(updated)
        )
    except Exception as e:
        logger.error(f"更新对话失败: {str(e)}")
        return ResponseFactory.error(
            code="CONVERSATION_UPDATE_FAILED",
            msg=f"更新对话失败: {str(e)}"
        )


# --------------------------------------------------------
# 删除对话
# --------------------------------------------------------
@conversations_bp.route('/<int:conversation_id>', methods=['DELETE'])
@jwt_required()
def delete_conversation(conversation_id):
    try:
        user_id = get_jwt_identity()
        conversation = conversation_service.get_conversation_by_id(conversation_id, user_id)

        if not conversation:
            return ResponseFactory.error(
                code="CONVERSATION_NOT_FOUND",
                msg="对话不存在或无权限访问"
            )

        conversation_service.delete_conversation(conversation_id, user_id)

        return ResponseFactory.success(
            msg="删除成功"
        )
    except Exception as e:
        logger.error(f"删除对话失败: {str(e)}")
        return ResponseFactory.error(
            code="CONVERSATION_DELETE_FAILED",
            msg=f"删除对话失败: {str(e)}"
        )


# --------------------------------------------------------
# 发送消息（核心接口，保存消息到数据库）
# --------------------------------------------------------
@conversations_bp.route('/<int:conversation_id>/messages', methods=['POST'])
@jwt_required()
def send_message(conversation_id):    
    try:
        user_id = get_jwt_identity()
        logger.info(f"用户 {user_id} 向对话 {conversation_id} 发送消息")

        # 1. 校验对话权限
        conversation = conversation_service.get_conversation_by_id(conversation_id, user_id)
        if not conversation:
            logger.warning(f"用户 {user_id} 尝试访问不存在或无权限的对话 {conversation_id}")
            return ResponseFactory.error(
                code="CONVERSATION_NOT_FOUND",
                msg="对话不存在或无权限访问"
            )

        if not request.is_json:
            logger.warning(f"用户 {user_id} 向对话 {conversation_id} 发送消息请求格式错误，不是 JSON")
            return ResponseFactory.error(
                code="INVALID_CONTENT_TYPE",
                msg="必须是 JSON 请求"
            )

        data = request.get_json()
        logger.info(f"用户 {user_id} 向对话 {conversation_id} 发送消息请求数据: {data}")
        
        content = data.get("content", "").strip()

        if not content:
            logger.warning(f"用户 {user_id} 向对话 {conversation_id} 发送空消息")
            return ResponseFactory.error(
                code="INVALID_MESSAGE_CONTENT",
                msg="消息内容不能为空"
            )

        logger.info(f"用户 {user_id} 向对话 {conversation_id} 发送消息内容: {content[:100]}...")
        
        # 2. 先保存用户消息到数据库
        message = message_service.create_message(
            conversation_id=conversation_id,
            role=MessageRole.USER,
            content=content
        )
        logger.info(f"用户 {user_id} 向对话 {conversation_id} 发送的消息已保存到数据库，消息ID: {message.id}")

        # 获取历史记录用于上下文
        history_msgs = message_service.get_messages_by_conversation(conversation_id, limit=10)
        logger.info(f"获取对话 {conversation_id} 的历史消息，共 {len(history_msgs)} 条")
        
        # 将 DB message 转为 agent 需要的 dict 格式
        agent_history = [msg.to_agent_format() for msg in history_msgs]
        logger.debug(f"对话 {conversation_id} 的历史消息转换为 agent 格式完成")

        # 3. 定义流式生成器
        def generate():
            logger.info(f"开始为对话 {conversation_id} 生成 AI 响应")
            agent_service = AgentService()
            
            # 实时产生数据
            for event_json in agent_service.handle_user_message_stream(
                str(conversation_id), content, agent_history
            ):
                # SSE 格式: "data: <content>\n\n"
                logger.debug(f"对话 {conversation_id} 生成 SSE 事件: {event_json[:100]}...")
                yield f"data: {event_json}\n\n"
            
            # 结束信号
            logger.info(f"对话 {conversation_id} 的 AI 响应生成完成")
            yield "data: [DONE]\n\n"
        
        # 4. 【修复】添加 headers 禁止缓冲
        from flask import Response, stream_with_context
        response = Response(stream_with_context(generate()), mimetype='text/event-stream')
        response.headers['X-Accel-Buffering'] = 'no'  # 关键：禁止 Nginx 缓冲
        response.headers['Cache-Control'] = 'no-cache'
        logger.info(f"返回对话 {conversation_id} 的流式响应")
        return response

    except Exception as e:
        logger.error(f"用户 {user_id} 向对话 {conversation_id} 发送消息失败: {str(e)}", exc_info=True)
        return ResponseFactory.error(
            code="MESSAGE_SEND_FAILED",
            msg=f"发送消息失败: {str(e)}"
        )


# --------------------------------------------------------
# 获取消息列表
# --------------------------------------------------------
@conversations_bp.route('/<int:conversation_id>/messages', methods=['GET'])
@jwt_required()
def get_messages(conversation_id):
    try:
        user_id = get_jwt_identity()
        logger.info(f"用户 {user_id} 请求获取对话 {conversation_id} 的消息列表")
        
        conversation = conversation_service.get_conversation_by_id(conversation_id, user_id)

        if not conversation:
            logger.warning(f"用户 {user_id} 尝试访问不存在或无权限的对话 {conversation_id} 的消息列表")
            return ResponseFactory.error(
                code="CONVERSATION_NOT_FOUND",
                msg="对话不存在或无权限访问"
            )

        msgs = message_service.get_messages_by_conversation(conversation_id)
        logger.info(f"用户 {user_id} 成功获取对话 {conversation_id} 的消息列表，共 {len(msgs)} 条消息")

        return ResponseFactory.success(
            data=[message_schema.dump(m) for m in msgs]
        )
    except Exception as e:
        logger.error(f"用户 {user_id} 获取对话 {conversation_id} 消息列表失败: {str(e)}", exc_info=True)
        return ResponseFactory.error(
            code="MESSAGES_FETCH_FAILED",
            msg=f"获取消息列表失败: {str(e)}"
        )
